/*!
\copyright  Copyright (c) 2023 Qualcomm Technologies International, Ltd.
            All Rights Reserved.
            Qualcomm Technologies International, Ltd. Confidential and Proprietary.
\file
\defgroup   list list
\ingroup vm_libs
\brief      List debug helpers
*/

#ifndef LIST_DEBUG_H_
#define LIST_DEBUG_H_

#include "list.h"
#include <logging.h>

/*\{*/

#define ASSERT_NOT_NULL(ptr)    PanicFalse(ptr != NULL)
#define ASSERT_VALID_HANDLE_REFERENCE(reference) do{ASSERT_NOT_NULL(reference); ASSERT_NOT_NULL(*reference);}while(0)

typedef struct {
    unsigned current_count;
    unsigned peak_count;
} list_node_trace_stats_t;

/**
 * \brief Add a new node to the debug tracing
 *
 * \details During list manipulations the location of the list can change on some implementations.
 *          Therefore the both the previous and current list locations are used
 *          to update nodes referring to the old list if necessary
 * 
 * \param [in] new_list: The new list the node belongs to (could be same as old_list)
 * \param [in] old_list: The old list the node belongs to (could be same as new_list)
 * \param [in] new_node: The new node to be added to the debug tracing
 * \param [in] owner: A string representing the owner of this node. These helpers don't require any specific format
*/
void ListDebugAddNodeTrace(const list_t new_list, const list_t old_list, const void* new_node, const char *owner);

/**
 * \brief Remove a node from the debug tracing
 *
 * \details During list manipulations the location of the list can change on some implementations.
 *          Therefore the both the previous and current list locations are used
 *          to update nodes referring to the old list if necessary
 * 
 * \param [in] new_list: The new list the node belongs to (could be same as old_list)
 * \param [in] old_list: The old list the node belongs to (could be same as new_list)
 * \param [in] remove_node: The node to be removed from the debug tracing
*/
void ListDebugRemoveNodeTrace(const list_t new_list, const list_t old_list, const void* remove_node);

/**
 * \brief Remove a whole list from the debug tracing
 *
 * \details Removes a list and all associated nodes from the debug tracing
 * 
 * \param [in] list: The list to be removed from the debug tracing
*/
void ListDebugDestroyTrace(const list_t list);

/**
 * \brief Get Stats of node trace tracking
 *
 * \details This could be used to tune the trace buffer to an optimal size
 * 
 * \return A pointer to the struct that contains stats like current count and peak count. \see list_node_trace_stats_t
*/
const list_node_trace_stats_t* ListDebugGetNodeTraceStats(void);

#ifdef SIMULATOR

void ListDebugResetNodeTraceStats(void);

#endif

/*\}*/

#endif /* LIST_DEBUG_H_ */
